package config

import (
	"com.yy.api/common/logger"
	"fmt"
	"github.com/spf13/viper"
)

type Config struct {
	Application AppConfig
	Database    DBConfig
	Redis       RedisConfig
	Agent       AgentConfig
}

func LoadConfig(configPath string, args ...string) *Config {
	var cfg Config

	configType := "yaml"
	configName := "app"

	if len(args) >= 1 {
		configName = args[0]
	}
	if len(args) >= 2 {
		configType = args[1]
	}

	viper.AddConfigPath(configPath)
	viper.SetConfigType(configType)
	viper.SetConfigName(configName)
	if err := viper.ReadInConfig(); err != nil {
		panic(err)
	}
	if err := viper.Unmarshal(&cfg); err != nil {
		logger.Default.Errorf("unable to decode into struct: %w", err)
	}
	logger.Default.Infof("app.yaml 配置文件加载成功,%s", cfg)
	return &cfg
}

type AppConfig struct {
	Name string `yaml:"name"`
	Port string `yaml:"port"`
}

func (c *Config) LoadAppConfig() *AppConfig {
	return &c.Application
}
func (ac *AppConfig) GetPort() string {
	return fmt.Sprintf(":%s", ac.Port)
}

type DBConfig struct {
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Name     string `yaml:"dbName"`
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Timeout  string `yaml:"timeout"`
}

func (c *Config) LoadDBConfig() *DBConfig {
	return &c.Database
}
func (db *DBConfig) GetConnectionString() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local&timeout=%s",
		db.User, db.Password, db.Host, db.Port, db.Name, db.Timeout)
}

type RedisConfig struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Password string `yaml:"password"`
	DB       int    `yaml:"db"`
}

func (c *Config) LoadRedisConfig() *RedisConfig {
	return &c.Redis
}
func (rc *RedisConfig) GetAddrString() string {
	return fmt.Sprintf("%s:%s", rc.Host, rc.Port)
}

type AgentConfig struct {
	Host string `yaml:"host"`
	Port string `yaml:"port"`
}

func (c *Config) LoadAgentConfig() *AgentConfig {
	return &c.Agent
}
func (ac *AgentConfig) GetAddrString() string {
	return fmt.Sprintf("%s:%s", ac.Host, ac.Port)
}
